import { useEffect, useRef, useState, useCallback, useMemo } from "react";
import { Input, Modal, Button, Radio, Select, Slider } from "antd";
import { cloneDeep, find, findIndex, remove } from "lodash";
import classNames from "classnames";
import QRCode from "qrcode.react";
import IconFont from "@/components/IconFont";
import BarCode from "./BarCode";
import styles from "./index.module.less";
import SubTitle from "@/pages/OrderModule/common/components/SubTitle";
import { getPxMm } from "@/utils/utils.jsx";
import { getCurrentUser } from "@/utils/authority";
import BarCodeTool from "./BarCodeTool";

const { TextArea } = Input;
const { Option } = Select;

const TemplateLeft = ({ currId, sizeScale, weight, height, viewContent, updateData, updateId }) => {
	const widthPx = useMemo(() => {
		return weight * getPxMm();
	}, [weight]);

	const heightPx = useMemo(() => {
		return height * getPxMm();
	}, [height]);

	//控制鼠标是否按下
	const isDown = useRef(false);

	//方向控制
	const direction = useRef(null);

	//初始数据，不需要重新render，是用useRef；
	const oriPos = useRef({
		top: 0,
		left: 0,
		cX: 0,
		cY: 0
	});

	useEffect(() => {
		if (currId) {
			const obj = find(viewContent, ["id", currId]);
			setStyle(obj);
		}
	}, [currId]);

	//初始化样式
	const [style, setStyle] = useState({});

	//鼠标被按下
	const onMouseDown = (dir, e) => {
		// 阻止事件冒泡
		e.stopPropagation();

		// 保存方向。
		direction.current = dir;
		isDown.current = true;

		// 然后鼠标坐标是
		const cY = e.clientY; // clientX 相对于可视化区域
		const cX = e.clientX;
		oriPos.current = {
			...style,
			cX,
			cY
		};
	};

	//鼠标移动
	const onMouseMove = e => {
		// 判断鼠标是否按住
		if (!isDown.current) {
			return;
		}
		const newStyle = transform(direction, oriPos, e);
		setStyle(newStyle);
	};

	//鼠标被抬起
	const onMouseUp = e => {
		if (isDown.current) {
			isDown.current = false;
			//鼠标抬起的时候进行赋值
			const arr = [...viewContent];
			const obj = find(arr, ["id", currId]);
			if (obj) {
				obj.left = style.left;
				obj.top = style.top;
				obj.width = style.width;
				obj.height = style.height;
				updateData(arr);
			}
		}
	};

	/**
	 * 元素变化。 方法放在组件外部或者其他地方。
	 * @param direction  方向 // move 移动 / 'e', 'w', 's', 'n', 'ne', 'nw', 'se', 'sw'
	 * @param oriPos  鼠标按下时所记录的坐标
	 * @param e        事件event
	 */
	const transform = (direction, oriPos, e) => {
		const style = { ...oriPos.current };
		const offsetX = e.clientX - oriPos.current.cX;
		const offsetY = e.clientY - oriPos.current.cY;

		//二维码宽高保持一致
		const obj = find(viewContent, ["id", currId]);

		switch (direction.current) {
			// 拖拽移动
			case "move":
				// 元素当前位置 + 偏移量
				const top = oriPos.current.top + offsetY;
				const left = oriPos.current.left + offsetX;
				// 限制必须在这个范围内移动 画板的高度-元素的高度
				style.top = Math.max(0, Math.min(top, heightPx - style.height));
				style.left = Math.max(0, Math.min(left, widthPx - style.width));
				break;

			// 东
			case "E":
				// 向右拖拽添加宽度
				style.width += offsetX;
				break;

			// 西
			case "W":
				// 增加宽度、位置同步左移
				style.width -= offsetX;
				style.left += offsetX;
				break;

			// 南
			case "S":
				style.height += offsetY;
				break;

			// 北
			case "N":
				style.height -= offsetY;
				style.top += offsetY;
				break;

			// 东北
			case "NE":
				style.height -= offsetY;
				style.top += offsetY;
				style.width += offsetX;
				break;

			// 西北
			case "NW":
				style.height -= offsetY;
				style.top += offsetY;
				style.width -= offsetX;
				style.left += offsetX;
				break;

			// 东南
			case "SE":
				style.height += offsetY;
				style.width += offsetX;
				break;

			// 西南
			case "SW":
				style.height += offsetY;
				style.width -= offsetX;
				style.left += offsetX;
				break;
		}

		//手动限制一下范围
		const { left, top, height, width } = style;
		if (width + left > widthPx) {
			style.width = widthPx - left;
		}
		if (left < 0) {
			style.left = 0;
		}
		if (top + height > heightPx) {
			style.height = heightPx - top;
		}
		if (top < 0) {
			style.top = 0;
		}

		if (obj.type == "customQrCodes") {
			style.width = style.height;
		}

		style.width = Math.max(style.width, 8);
		style.height = Math.max(style.height, 8);

		return style;
	};

	//文本框输入后 update
	const handleTextChange = (e, id) => {
		let value = e.target.value;
		const arr = [...viewContent];
		const obj = find(arr, ["id", id]);
		if (value) {
			if (value.length > 100) {
				value = value.slice(0, 100);
				Modal.info({
					content: "最多可以输入100个字符"
				});
			}
		} else {
			value = "";
		}

		obj.value = value;
		updateData(arr);
	};

	//点击选中需要操作的数据框
	const handleSelect = (e, id) => {
		e.stopPropagation();
		if (id == currId) {
			return;
		} else {
			updateId(id);
		}
	};

	//删除数据
	const handleDeleteData = id => {
		const arr = [...viewContent];
		remove(arr, v => v.id == id);
		updateId(undefined);
		updateData(arr);
	};

	//切换字段显示
	const handleChangeField = (id, type, bool) => {
		const index = findIndex(viewContent, ["id", id]);
		if (bool) {
			viewContent[index].rebaseValue = viewContent[index].value;
		}
		if (type == "customQrCodes") {
			viewContent[index].value = bool ? "#goodsUniqueCode#" : viewContent[index].rebaseValue || "http://www.zhaojiafang.com/";
		} else {
			viewContent[index].value = bool ? "#goodsUniqueCode#" : viewContent[index].rebaseValue || "12345678";
		}
		updateData([...viewContent]);
	};

	//改变表格列宽比
	const handleChangePercent = (id, e) => {
		const index = findIndex(viewContent, ["id", id]);
		viewContent[index].percentLeft = e;
		updateData([...viewContent]);
	};

	//表格标题更改
	const handleTitleChange = (e, id, type) => {
		const obj = find(viewContent, ["id", id]);
		if (obj) {
			obj[`${type}Header`] = e.target.value;
		}
		updateData([...viewContent]);
	};

	//单选打印字段选择
	const handleChangeRaido = (e, id) => {
		const obj = find(viewContent, ["id", id]);
		obj.value = e.target.value;
		updateData([...viewContent]);
	};

	//条形码编辑回调
	const handleChange = (obj, id) => {
		const index = findIndex(viewContent, ['id', id]);
		viewContent[index] = obj;
		updateData([...viewContent]);
	}

	//渲染工具操作属性栏
	const renderToolContent = v => {
		const { type, id, value } = v;

		if (type == "customQrCodes") {
			const isField = ["#goodsUniqueCode#", "#productCode#", "#originalProductCode#"].includes(value);
			return (
				<div className={classNames(styles.operaWrapLeft, styles.operaWrap2)}>
					{isField ? (
						<Radio.Group value={value} onChange={e => handleChangeRaido(e, id)}>
							<Radio value="#goodsUniqueCode#">商品唯一码</Radio>
							<Radio value="#productCode#">系统商品编码</Radio>
							<Radio value="#originalProductCode#">原始编码</Radio>
						</Radio.Group>
					) : (
						<div style={{ display: "flex", alignItems: "center" }}>
							<span>二维码信息：</span>
							<Input style={{ flex: 1 }} onChange={e => handleTextChange(e, id)} value={value} placeholder="请输入二维码信息" />
						</div>
					)}
					<Button onClick={() => handleChangeField(id, type, !isField)} style={{ marginTop: 4 }}>
						切换{isField ? "链接" : "字段"}方式
					</Button>
				</div>
			);
		} else if (type == "customBarCodes" || type == 'uniqueCode') {
			return <BarCodeTool {...v} handleChange={obj => handleChange(obj, id)}/>
			const isField = [
				"#goodsUniqueCode#",
				"#originalProductCode#",
				"#sysGoodsCode#",
				"#systemOrderNumber#",
				"#shopOrderNumber#"
			].includes(value);
			return (
				<div className={classNames(styles.operaWrapLeft, isField ? styles.operaWrap5 : styles.operaWrap2)}>
					{isField ? (
						<Radio.Group value={value} onChange={e => handleChangeRaido(e, id)}>
							<Radio value="#goodsUniqueCode#">商品唯一码</Radio>
							<br />
							<Radio value="#sysGoodsCode#">系统商品编码</Radio>
							<br />
							<Radio value="#originalProductCode#">原始编码</Radio>
							<br />
							<Radio value="#systemOrderNumber#">系统订单号</Radio>
							<Radio value="#shopOrderNumber#">店铺订单号</Radio>
						</Radio.Group>
					) : (
						<div style={{ display: "flex", alignItems: "center" }}>
							<span>条形码信息：</span>
							<Input style={{ flex: 1 }} onChange={e => handleTextChange(e, id)} value={value} placeholder="请输入条形码信息" />
						</div>
					)}
					<Button onClick={() => handleChangeField(id, type, !isField)} style={{ marginTop: 4 }}>
						切换{isField ? "链接" : "字段"}方式
					</Button>
				</div>
			);
		} else if (type == "table") {
			const { id, data = [], percentLeft, leftHeader, rightHeader } = v;
			return (
				<>
					<div className={classNames(styles.operaWrapLeft, styles.operaWrap3)}>
						{/* <div style={{ display: 'flex', alignItems: 'center', width:"100%" }}>
							<span>左右列宽占比：</span>
							<Slider value={percentLeft} onChange={(e)=>handleChangePercent(id, e)} style={{flex:1}} max={80} min={20}/>
						</div> */}
						<div style={{ display: "flex", alignItems: "center", marginTop: 6 }}>
							<span>请输入左侧标题：</span>
							<Input
								style={{ flex: 1 }}
								onChange={e => handleTitleChange(e, id, "left")}
								value={leftHeader}
								maxLength={5}
								placeholder="请输入"
							/>
						</div>
						<div style={{ display: "flex", alignItems: "center", marginTop: 6 }}>
							<span>请输入右侧标题：</span>
							<Input
								style={{ flex: 1 }}
								onChange={e => handleTitleChange(e, id, "right")}
								value={rightHeader}
								maxLength={5}
								placeholder="请输入"
							/>
						</div>
					</div>
				</>
			);
		}
	};

	const currentUuid = getCurrentUser()?.uuid

	//渲染item 主体部分
	const renderMainMsg = v => {
		const { type, width, height, value, id } = v;
		if (type == "customTexts") {
			//自定义文本框
			if (currId == id) {
				return (
					<TextArea
						value={value}
						onChange={e => handleTextChange(e, id)}
						placeholder="请输入文本内容"
						style={{ width: "100%", height: "100%", border: "none", fontSize: sizeScale * 25, lineHeight: 1, padding: 0 }}
					/>
				);
			} else {
				const arr = formatRowTextArr(width, value);
				return arr.map((item, index) => (
					<p key={`${item}${index}`} style={{ fontSize: sizeScale * 25 }}>
						{item}
					</p>
				));
			}
		} else if (type == "customQrCodes") {
			//自定义二维码
			return <QRCode value={value} size={width} fgColor="#000000" />;
		} else if (type == "customBarCodes" || type == "uniqueCode") {
			//自定义条形码 （及唯一码）
			return (
				<BarCode
					value={
						["#goodsUniqueCode#", "#systemOrderNumber#", "#productCode#", '#shopOrderNumber#'].includes(value)
							? "88888888"
							: value
					}
					height={height}
					displayValue={true}
				/>
			);
		} else if (type == "table") {
			// return <div onDoubleClick={()=>console.log('double')}>{value}</div>
			const { data = [{ customId: "actual-only-one" }], leftHeader, rightHeader, percentLeft = 50 } = v;

			return (
				<>
					<div style={{ display: "flex", flexWrap: "wrap", height: 24 }} key="headerTitle">
						<div style={{ width: `${percentLeft}%`, border: "1px solid #ccc" }}>{leftHeader}</div>
						<div style={{ width: `${100 - percentLeft}%`, border: "1px solid #ccc", borderLeft: "none" }}>{rightHeader}</div>
					</div>

					{data.map((item, index) => {
						return (
							<div style={{ display: "flex", flexWrap: "wrap", height: 96 }} key={item.customId}>
								<div style={{ width: `${percentLeft}%`, height: "100%" }} className={styles.leftColumn}></div>
								<div style={{ width: `${100 - percentLeft}%`, height: "100%" }} className={styles.rightColumn}></div>
							</div>
						);
					})}
				</>
			);
		} else {
			// 用户定制模板字段大小
			const bigValueMap = {
				'722324': ['分拣框'],
				'727786': ['订单单多件'],
			}
			const littleBigValueMap = {
				'722324': ['用户简称', '款式编码', '商品编码', '货品总数', '订单单多件'],
				'726536': ['分拣框', '用户简称', '款式编码', '货品总数', '订单单多件'],
				'727786': ['用户简称', '分拣框', '商品编码', '货品总数'],
				'721261': ['用户简称', '商品编码', '订单单多件', '货品总数', '分拣框'],
			}
			if (bigValueMap[currentUuid]?.includes(value)) {
				return <div style={{ font: '18px monospace' }}>{value}</div>
			} else if (littleBigValueMap[currentUuid]?.includes(value)) {
				return <div style={{ font: '15px monospace' }}>{value}</div>
			}
			return value;
		}
	};

	const formatRowTextArr = (width, value) => {
		//按照字节长度
		const len = Math.floor(width / ((sizeScale * 25) / 2));
		const newArr = [];
		if (value) {
			const rowArr = value.split("\n");
			rowArr.map(item => {
				if (item) {
					let str = "",
						num = 0;
					for (let i = 0; i < item.length; i++) {
						const zijie = item.charCodeAt(i) > 255 ? 2 : 1;
						if (num + zijie <= len) {
							str += item.charAt(i);
							num += zijie;
						} else {
							newArr.push(str);
							str = item.charAt(i);
							num = zijie;
						}
						if (i == item.length - 1) {
							newArr.push(str);
						}
					}
				} else {
					newArr.push("");
				}
			});
		}
		// if(value.includes('5678')){
		// 	console.log(len,newArr)
		// }
		return newArr;
	};

	//拖拽点
	const dropPointArr = useCallback(v => {
		if (v.type == "goodsUniqueCode") {
			//（唯一码）
			return ["D"];
		} else if (v.type == "customQrCodes") {
			//二维码
			return ["D", "NW", "SE", "SW"];
		} else if (v.type == "table") {
			//表格
			return ["E", "W", "D"];
		} else {
			return ["E", "W", "S", "N", "D", "NW", "SE", "SW"]; //删除、西北、东南、西南
		}
	}, []);

	return (
		<div style={{ font: `${sizeScale * 25}px monospace`, background: "#FAFAFA", flex: "1" }}>
			<div style={{ height: "32px", background: "#FFF" }}>
				<SubTitle title={"预览"} as="s2" symbol />
			</div>
			<div
				style={{
					width: widthPx,
					height: heightPx,
					background: "#fff",
					boxShadow: "0px 0px 10px rgb(79 94 112 / 10%)",
					position: "relative",
					marginLeft: "14px",
					top: "16px"
				}}
				onMouseMove={onMouseMove}
				onMouseUp={onMouseUp}
			>
				<div className={styles.rulWrapper}>
					<img
						className={styles.hImg}
						src=""
					/>
					<img
						className={styles.vImg}
						src=""
					/>
				</div>
				{viewContent.map(v => {
					const { id, addIndex = 0 } = v;
					if (id == currId) {
						const dirArr = dropPointArr(v);
						return (
							<div
								key={id}
								className={styles.dragItem}
								onClick={e => handleSelect(e, id)}
								style={{ ...style, zIndex: `${addIndex + 1000}`, border: "1px solid #0165D5" }}
								onMouseDown={e => onMouseDown("move", e)}
							>
								{renderToolContent(v)}
								<div className={styles.renderMsg}>{renderMainMsg(v)}</div>
								{/* 拖拽点 */}
								{dirArr.map(item => {
									if (item == "D") {
										return (
											<div key={item} onClick={() => handleDeleteData(id)} className={styles.pointsDel}>
												<IconFont className type="iconclose" />
											</div>
										);
									} else {
										return (
											<div
												key={item}
												onMouseDown={e => onMouseDown(item, e)}
												className={classNames(styles.controlPoint, styles[`point${item}`])}
											></div>
										);
									}
								})}
							</div>
						);
					} else {
						return (
							<div key={id} className={styles.dragItem} onClick={e => handleSelect(e, id)} style={{ ...v, zIndex: addIndex }}>
								<div className={styles.renderMsg}>{renderMainMsg(v)}</div>
							</div>
						);
					}
				})}
			</div>
		</div>
	);
};

export default TemplateLeft;
